package com.niiwoo.civet.trade.service.local.org;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.civet.base.enums.FeeTypeEnum;
import com.niiwoo.civet.base.enums.OrderTradeSourceEnum;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.*;
import com.niiwoo.civet.trade.dto.request.myloan.LoanVoucherAuditInfoQueryRequestDTO;
import com.niiwoo.civet.trade.dto.response.LendOrderResponseDTO;
import com.niiwoo.civet.trade.dto.response.myloan.LoanVoucherAuditInfoQueryResponseDTO;
import com.niiwoo.civet.trade.dto.response.org.AssetOrgProjectResponseDTO;
import com.niiwoo.civet.trade.dto.response.org.ProjectBorrowerPlanNewResponseDTO;
import com.niiwoo.civet.trade.enums.LoanVoucherEnum;
import com.niiwoo.civet.trade.enums.ProjectStatusEnum;
import com.niiwoo.civet.trade.service.local.newRefund.common.RefundLocalService;
import com.niiwoo.civet.trade.service.local.refund.CommonLocalService;
import com.niiwoo.civet.trade.utils.RepaymentUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class OrgProjectLocalService {
	
	@Autowired
	private AssetOrgProjectMapperExt assetOrgProjectMapperExt;
	@Autowired
	private ProjectBorrowerPlanNewMapperExt projectBorrowerPlanNewMapperExt;
	@Autowired
	private ProjectBorrowerPlanDetailMapperExt projectBorrowerPlanDetailMapperExt;
	@Autowired
	private LendOrderMapper lendOrderMapper;
	@Autowired
	private ProjectContractMapperExt projectContractMapperExt;
	@Autowired
	private ProjectMapperExt projectMapperExt;
	@Autowired
	private ProjectFlowedMapperExt projectFlowedMapperExt;
	@Autowired
	private LoanVoucherAuditMapperExt loanVoucherAuditMapper;
	@Autowired
	private LoanVoucherImgMapperExt loanVoucherImgMapper;

	@Autowired
	private RefundLocalService refundLocalService;

	@Autowired
	private CommonLocalService commonLocalService;

	@Transactional
	public AssetOrgProject getAsserOrgProjectFromMaster(Long projectId) {
		return assetOrgProjectMapperExt.selectByPrimaryKey(projectId);
	}

	/**
	 * 查询机构第三方标的信息
	 * @param orgId
	 * @param orderId
	 * @return
	 */
	@Transactional
	public AssetOrgProjectResponseDTO getAsserOrgProject(String orgId,Long orderId) {
		AssetOrgProject assetOrgProject = assetOrgProjectMapperExt.selectByOrgIdAndOrderId(orgId, orderId);
		if (assetOrgProject == null) {
			return null;
		}

		AssetOrgProjectResponseDTO dto=new AssetOrgProjectResponseDTO();
		dto.setProjectId(assetOrgProject.getProjectId());
		dto.setOrderId(assetOrgProject.getOrderId());
		dto.setOrgId(assetOrgProject.getOrgId());
		dto.setBorrowerName(assetOrgProject.getBorrowerName());
		dto.setBorrowerMobile(assetOrgProject.getBorrowerMobile());
		dto.setAmount(assetOrgProject.getAmount());
		dto.setApplyTime(assetOrgProject.getApplyTime());
		dto.setFundraisingEndTime(assetOrgProject.getFundraisingEndTime());
		dto.setProjectStatus(assetOrgProject.getProjectStatus());
		dto.setFlowReason(assetOrgProject.getFlowReason());

		Project project = projectMapperExt.selectByPrimaryKey(assetOrgProject.getProjectId());
		dto.setBorrowerUserId(project.getBorrowUserId());
		dto.setProjectStatus(project.getStatus());
		dto.setProjectSubStatus(project.getSubStatus());
		dto.setFullSuccessTime(project.getFullSuccessTime());

		return dto;
	}

	/**
	 * 询第三方机构的标的信息查
	 * @param projectId
	 * @return
	 */
	@Transactional
	public AssetOrgProjectResponseDTO getAsserOrgProject(Long projectId) {
		AssetOrgProject assetOrgProject = assetOrgProjectMapperExt.selectByPrimaryKey(projectId);
		if (assetOrgProject == null) {
			return null;
		}

		AssetOrgProjectResponseDTO dto = new AssetOrgProjectResponseDTO();

		dto.setProjectId(assetOrgProject.getProjectId());
		dto.setOrderId(assetOrgProject.getOrderId());
		dto.setOrgId(assetOrgProject.getOrgId());
		dto.setBorrowerUserId(assetOrgProject.getBorrowUserId());
		dto.setBorrowerName(assetOrgProject.getBorrowerName());
		dto.setBorrowerMobile(assetOrgProject.getBorrowerMobile());
		dto.setAmount(assetOrgProject.getAmount());
		dto.setApplyTime(assetOrgProject.getApplyTime());
		dto.setFundraisingEndTime(assetOrgProject.getFundraisingEndTime());
		dto.setProjectStatus(assetOrgProject.getProjectStatus());
		dto.setFlowReason(assetOrgProject.getFlowReason());

		Project project = projectMapperExt.selectByPrimaryKey(assetOrgProject.getProjectId());
		dto.setBorrowerUserId(project.getBorrowUserId());
		dto.setProjectStatus(project.getStatus());
		dto.setProjectSubStatus(project.getSubStatus());
		dto.setFullSuccessTime(project.getFullSuccessTime());

		return dto;
	}

	/**
	 * 同步标的状态
	 * @param projectId
	 */
	@Transactional
	public void syncProjectStatus(Long projectId) {
		AssetOrgProject assetOrgProject = new AssetOrgProject();
		assetOrgProject.setProjectId(projectId);

		Project project = projectMapperExt.selectByPrimaryKey(projectId);
		if (project == null) {
			return;
		}

		assetOrgProject.setProjectStatus(project.getStatus());
		assetOrgProject.setSubStatus(project.getSubStatus());

		if (ProjectStatusEnum.MISCARRY.getStatus().equals(project.getStatus())) {
			ProjectFlowed projectFlowed = projectFlowedMapperExt.selectByPrimaryKey(projectId);
			if (projectFlowed != null && StringUtils.isNotBlank(projectFlowed.getFlowedReason())) {
				assetOrgProject.setFlowReason(projectFlowed.getFlowedReason() + ":" + projectFlowed.getRemark());
			}
		}

		assetOrgProjectMapperExt.updateByPrimaryKeySelective(assetOrgProject);
	}

	/**
	 * 计划任务同步标的状态
	 */
	@Transactional
	public void syncProjectStatusByJob() {
		List<AssetOrgProject> orgProjectList = assetOrgProjectMapperExt.selectForSyncProjectStatus();
		orgProjectList.forEach(p -> {
			syncProjectStatus(p.getProjectId());
		});
	}

	/**
	 * 查询还款计划
	 * @param projectId
	 * @return
	 */
	public List<ProjectBorrowerPlanNewResponseDTO> getProjectBorrowerPlanNew(Long projectId) {
		List<ProjectBorrowerPlanNewResponseDTO>list=Lists.newArrayList();
		List<ProjectBorrowerPlanNew> projectBorrowerPlanNew=projectBorrowerPlanNewMapperExt.selectByProjectId(projectId);
		log.info("查询还款计划,标的ID={},还款计划列表={}", projectId, JSON.toJSONString(projectBorrowerPlanNew));
		for(ProjectBorrowerPlanNew plan:projectBorrowerPlanNew){
			ProjectBorrowerPlanNewResponseDTO dto=new ProjectBorrowerPlanNewResponseDTO();
			dto.setPeriod(plan.getPeriod());
			dto.setRefundDate(plan.getRefundDate().getTime());

			if (plan.getOverDate() != null) {
				dto.setRealRefundDate(plan.getOverDate().getTime()); // 实际还款时间

				OrderTradeSourceEnum tradeSource = refundLocalService.queryLastRefundOrderTradeSourceByProjectIdAndPeriod(projectId, plan.getPeriod());
				if (OrderTradeSourceEnum.WITHHOLD.equals(tradeSource)) {
					dto.setRefundSource((byte) 2); // 还款来源(1:充值还款、2:代扣还款)
				} else {
					dto.setRefundSource((byte) 1); // 还款来源(1:充值还款、2:代扣还款)
				}
			}

			//查询还款计划明细
			List<ProjectBorrowerPlanDetail>planDetail=projectBorrowerPlanDetailMapperExt.selectByPlanId(plan.getId());
			log.info("查询还款计划,标的ID={},还款计划ID={},还款计划明细列表={}", projectId, plan.getId(), JSON.toJSONString(planDetail));
			for(ProjectBorrowerPlanDetail detail:planDetail){
				if(FeeTypeEnum.CAPITAL.getValue().equals(detail.getFeeType())){//本金
					dto.setPrincipal(getAmountValue(detail.getMoney()));
					dto.setRepaidPrincipal(getAmountValue(detail.getRefundMoney()));
				}else if(FeeTypeEnum.INTEREST.getValue().equals(detail.getFeeType())){//利息
					dto.setInterest(getAmountValue(detail.getMoney()));
					dto.setRepaidInterest(getAmountValue(detail.getRefundMoney()));
				}else if(FeeTypeEnum.MANAGEMENT_FEE.getValue().equals(detail.getFeeType())){//平台管理费
					dto.setPlatformManageFee(getAmountValue(detail.getMoney()));
					dto.setRepaidPlatformManageFee(getAmountValue(detail.getRefundMoney()));
				}else if(FeeTypeEnum.GUARANTEE_FEE.getValue().equals(detail.getFeeType())){//担保服务费
					dto.setCommissionGuaranteFee(getAmountValue(detail.getMoney()));
					dto.setRepaidCommissionGuaranteFee(getAmountValue(detail.getRefundMoney()));
				}else if(FeeTypeEnum.PENALTY.getValue().equals(detail.getFeeType())){//罚息
					dto.setTotalPenalty(getAmountValue(detail.getMoney()));
					dto.setRepaidPenalty(getAmountValue(detail.getRefundMoney()));
				}else if(FeeTypeEnum.CONSULTING_FEE.getValue().equals(detail.getFeeType())){//咨询服务费
					dto.setRepaidConsultingFee(getAmountValue(detail.getRefundMoney()));
					dto.setShouldConsultingFee(getAmountValue(detail.getMoney()));
				}
			}

			// 逾期天数
			dto.setOverdueDays(getOverdueDays(plan.getRefundDate(), plan.getOverCurrentDate()));
			dto.setStatus(plan.getStatus());

			list.add(dto);
		}
		log.info("查询还款计划,标的ID={},响应结果={}", projectId, JSON.toJSONString(list));
		return list;
	}

	/**
	 * 计算逾期天数
	 * @param refundDate
	 * @param currentDate
	 * @return
	 */
    private int getOverdueDays(Date refundDate, Date currentDate) {
        int overdueDays = 0;

        if (currentDate == null) {
            currentDate = commonLocalService.getCurrentDate();
        }

        overdueDays = RepaymentUtil.getOverdueDay(refundDate, currentDate);
        if (overdueDays < 0) {
            overdueDays = 0;
        }

        return overdueDays;
    }

	/**
	 * 查询标的放款订单信息
	 * @param projectId
	 * @return
	 */
	public LendOrderResponseDTO getLendOrder(Long projectId) {
		LendOrder lendOrder=lendOrderMapper.selectByPrimaryKey(projectId);
		if(lendOrder==null){
			return null;
		}
		LendOrderResponseDTO dto=new LendOrderResponseDTO();
		dto.setProjectId(lendOrder.getProjectId());
		dto.setBorrowUserId(lendOrder.getBorrowUserId());
		dto.setBatchNo(lendOrder.getBatchNo());
		dto.setWithdrawOrderId(lendOrder.getWithdrawOrderId());
		dto.setProjectChangeStatus(lendOrder.getProjectChangeStatus());
		dto.setAccountingStatus(lendOrder.getAccountingStatus());
		dto.setStatus(lendOrder.getStatus());
		dto.setErrorCode(lendOrder.getErrorCode());
		dto.setErrorMessage(lendOrder.getErrorMessage());
		dto.setSuccessTime(lendOrder.getSuccessTime());
		dto.setOverTime(lendOrder.getOverTime());
		dto.setCreateTime(lendOrder.getCreateTime());
		dto.setUpdateTime(lendOrder.getUpdateTime());
		
		return dto;
	}

	/**
	 * 查询合同查看地址
	 * @param projectId
	 * @return
	 */
	public String getProjectContractViewUrl(Long projectId) {
		String contractViewUrl=projectContractMapperExt.findNewestByProjectIdAndContractType(projectId, (byte)1);
		return contractViewUrl;
	}
	
	/**
	 * 
	 * @param val
	 * @return
	 */
	private Double getAmountValue(BigDecimal val){
		BigDecimal zero=BigDecimal.ZERO;
		if(val==null){
			return zero.doubleValue();
		}
		return val.doubleValue();
	}

	/**
	 * 借款凭证信息读取
	 * @param requestDTO
	 * @return
	 */
	public LoanVoucherAuditInfoQueryResponseDTO loanVoucherAuditInfoQuery(LoanVoucherAuditInfoQueryRequestDTO requestDTO){
		String loginUserId = requestDTO.getLoginUserId(); //登录用户ID
		String borrowUserId = requestDTO.getBorrowUserId(); //借款人用户ID
		Long projectId = requestDTO.getProjectId();
		Project project = projectMapperExt.selectByPrimaryKey(projectId);
		LoanVoucherAudit loanVoucherAudit = loanVoucherAuditMapper.selectByUserIdProjectId(borrowUserId, projectId);
		LoanVoucherAuditInfoQueryResponseDTO respDTO = new LoanVoucherAuditInfoQueryResponseDTO();
		if (project != null && loanVoucherAudit == null){
			respDTO.setType(project.getType());
			respDTO.setLoanDesc(project.getTitle()); //借款描述
			respDTO.setContractAmount(project.getContractAmount());
			respDTO.setIsMasterBorrower(project.getIsMasterBorrower());
			respDTO.setLoanType(project.getLoanType());
			respDTO.setBorrowerType(project.getBorrowerType());
			respDTO.setFromSource(project.getFromSource());
		}
		if (project == null && loanVoucherAudit != null) {

			boolean isSelfQuery = this.isSelfQuery(borrowUserId, loginUserId); //是否为本人查询
			//后台配置不展示借款凭证信息，则返回空（自己查看自己的借款凭证除外）
			if (LoanVoucherEnum.IsShowEnum.NO_SHOW.getValue().equals(loanVoucherAudit.getIsShow())
					&& !isSelfQuery) {
				return null;
			}

			respDTO.setAuditStatus(loanVoucherAudit.getAuditStatus());
			respDTO.setAuditDesc(loanVoucherAudit.getAuditDesc());
			respDTO.setIsShow(loanVoucherAudit.getIsShow());
			//审核状态没有通过，则无需返回图片信息
			if (!LoanVoucherEnum.AuditStatusEnum.PASS.getStatus().equals(loanVoucherAudit.getAuditStatus())) {
				return respDTO;
			}

			List<LoanVoucherImg> loanVoucherImgList = loanVoucherImgMapper.selectByUserIdProjectIdVoucherAuditNo(borrowUserId, projectId, loanVoucherAudit.getVoucherAuditNo());
			if (CollectionUtils.isEmpty(loanVoucherImgList)) {
				return respDTO;
			}

			List<LoanVoucherAuditInfoQueryResponseDTO.LoanVoucherAuditImgResponseDTO> loanVoucherImgRespList = new ArrayList<>();
			for (LoanVoucherImg img : loanVoucherImgList) {
				String imgUrl = img.getImgUrl();//图片地址
				String imgReleaseUrl = img.getImgReleaseUrl();//图片打码后地址
				String imgThumbnailUrl = img.getImgThumbnailUrl();//图片缩略地址
				String imgReleaseThumbnailUrl = img.getImgReleaseThumbnailUrl();//图片打码后的缩略地址

				LoanVoucherAuditInfoQueryResponseDTO.LoanVoucherAuditImgResponseDTO impRespDTO = new LoanVoucherAuditInfoQueryResponseDTO.LoanVoucherAuditImgResponseDTO();

				impRespDTO.setImgUrl(this.getImgUrl(isSelfQuery, imgUrl, imgReleaseUrl));
				impRespDTO.setImgThumbnailUrl(this.getImgUrl(isSelfQuery, imgThumbnailUrl, imgReleaseThumbnailUrl));
				loanVoucherImgRespList.add(impRespDTO);
			}
			respDTO.setLoanVoucherImgList(loanVoucherImgRespList);
		}
		return respDTO;
	}

	/**
	 * 获取图片地址
	 * @param isSelfQuery
	 * @param imgUrl
	 * @param imgReleaseUrl
	 * @return
	 */
	private String getImgUrl(boolean isSelfQuery,String imgUrl,String imgReleaseUrl){
		if(isSelfQuery){
			return StringUtils.isNoneEmpty(imgUrl)?imgUrl:imgReleaseUrl;
		}
		return StringUtils.isNoneEmpty(imgReleaseUrl)?imgReleaseUrl:imgUrl;
	}

	/**
	 * 判断是否安全查询
	 * @param borrowUserId
	 * @param loginUserId
	 * @return
	 */
	private boolean isSelfQuery(String borrowUserId,String loginUserId){
		if(StringUtils.isEmpty(loginUserId)){
			return false;
		}
		return loginUserId.equals(borrowUserId);
	}
	/**
	 * 修改筹标结束时间
	 *
	 * @param orderId
	 */
	@Transactional
	public void updateFundraisingEndTime(String orgId, Long orderId) {
		AssetOrgProject assetOrgProject = assetOrgProjectMapperExt.selectByOrgIdAndOrderId(orgId, orderId);
		Project project = projectMapperExt.selectByPrimaryKey(assetOrgProject.getProjectId());

		AssetOrgProject params = new AssetOrgProject();
		params.setProjectId(assetOrgProject.getProjectId());
		params.setFundraisingEndTime(project.getInvestEndTime());
		assetOrgProjectMapperExt.updateByPrimaryKeySelective(params);
	}

	private void masterRouteOnly() {
		if (!HintManagerHolder.isMasterRouteOnly()) {
			HintManagerHolder.clear();
			HintManager hintManager = HintManager.getInstance();
			hintManager.setMasterRouteOnly();
		}
	}
}
